package com.wechat.back.aspect;

import com.alibaba.fastjson.JSON;
import com.wechat.back.anno.OptLog;
import com.wechat.back.mapper.OperationLogMapper;
import com.wechat.back.pojo.OperationLog;
import com.wechat.back.pojo.Place;
import com.wechat.back.utils.IpUtil;
import com.wechat.back.utils.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Map;

@Aspect
@Component
public class OperationLogAspect {
    @Autowired
    private OperationLogMapper operationLogMapper;

    @Pointcut("@annotation(com.wechat.back.anno.OptLog)")
    public void operationLogPointCut() {}

    /**
     * 过滤 MultipartFile 类型的参数
     */
    private Object[] filterMultipartFiles(Object[] args) {
        if (args == null) {
            return null;
        }
        Object[] filteredArgs = new Object[args.length];
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof MultipartFile) {
                MultipartFile file = (MultipartFile) args[i];
                filteredArgs[i] = "MultipartFile: " + file.getOriginalFilename();
            } else {
                filteredArgs[i] = args[i];
            }
        }
        return filteredArgs;
    }

    /**
     * 过滤 MultipartFile 类型的返回值
     */
    private Object filterMultipartFile(Object obj) {
        if (obj instanceof MultipartFile) {
            MultipartFile file = (MultipartFile) obj;
            return "MultipartFile: " + file.getOriginalFilename();
        }
        return obj;
    }

    @AfterReturning(value = "operationLogPointCut()", returning = "keys")
    public void saveOperationLog(JoinPoint joinPoint, Object keys) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        OperationLog operationLog = new OperationLog();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        OptLog optLog = method.getAnnotation(OptLog.class);
        operationLog.setOptModule(optLog.optModule());
        operationLog.setOptType(optLog.optType());
        operationLog.setOptDesc(optLog.optDesc());
        operationLog.setRequestMethod(request.getMethod());
        operationLog.setOptMethod(joinPoint.getTarget().getClass().getName() + "." + method.getName());

//        operationLog.setRequestParam(JSON.toJSONString(joinPoint.getArgs()));
//        operationLog.setResponseData(JSON.toJSONString(keys));
        // 序列化请求参数，排除 MultipartFile 类型
        Object[] args = joinPoint.getArgs();
        Object[] filteredArgs = filterMultipartFiles(args);
        operationLog.setRequestParam(JSON.toJSONString(filteredArgs));

        // 序列化返回值，排除 MultipartFile 类型
        Object filteredKeys = filterMultipartFile(keys);
        operationLog.setResponseData(JSON.toJSONString(filteredKeys));


        Map<String,Object> map = ThreadLocalUtil.get();
        if(map == null){
            operationLog.setUserId(0);
            operationLog.setNickname(" ");
        }else {
            // 获取用户id
            if (map.containsKey("id")) {
                Integer id = (Integer)map.get("id");
                operationLog.setUserId(id);
            } else if (map.containsKey("adminId")) {
                Integer id = (Integer) map.get("adminId");
                operationLog.setUserId(id);
            }
            // 获取用户名
            if (map.containsKey("username")) {
                String name = (String)map.get("username");
                operationLog.setNickname(name);
            } else if (map.containsKey("adminName")) {
                String name = (String) map.get("adminName");
                operationLog.setNickname(name);
            }
        }

//        String ipAddress = IpUtil.getIpAddress(request);

        String ipAddress = IpUtil.getIpAddress(request);
        operationLog.setIpAddress(ipAddress);
        try {
            operationLog.setIpSource(IpUtil.getIpSource(ipAddress));
        } catch (Exception e) {
            operationLog.setIpSource("Unknown");
            // 记录错误日志
            System.err.println("Error occurred while querying IP source for IP: " + ipAddress);
            e.printStackTrace();
        }
        operationLog.setIpSource(IpUtil.getIpSource(ipAddress));
        operationLog.setOptUri(request.getRequestURI());
        operationLog.setCreateTime(LocalDateTime.now());
        operationLog.setUpdateTime(LocalDateTime.now());

        operationLogMapper.insertLog(operationLog);
    }
}

